﻿using Nop.Admin.Models.WindAlert;
using Nop.Core;
using Nop.Core.Domain.Tasks;
using Nop.Core.Domain.WindAlert;
using Nop.Services.Configuration;
using Nop.Services.Helpers;
using Nop.Services.Stores;
using Nop.Services.Tasks;
using Nop.Services.WindAlert;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Kendoui;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Nop.Admin.Controllers
{
    public partial class WSettingController : BaseAdminController
    {
        #region Fields
        private readonly ISpotService _spotService;
        private readonly IWindDataService _windDataService;
        private readonly IWaveDataService _waveDataService;
        private readonly IForecastDataService _forecastDataService;
        private readonly IScheduleTaskService _scheduleTaskService;
        private readonly IDateTimeHelper _dateTimeHelper;

        private readonly ISettingService _settingService;
        private readonly IStoreService _storeService;
        private readonly IWorkContext _workContext;
        #endregion

        #region Constructors
        
        public WSettingController(
                ISpotService SpotService
            , IWindDataService WindDataService 
            ,IWaveDataService WaveDataService
             ,IForecastDataService ForecastDataService
            ,IScheduleTaskService scheduleTaskService
            ,IDateTimeHelper dateTimeHelper,
            ISettingService settingService,
            IStoreService storeService,
            IWorkContext workContext)
        {
            this._spotService = SpotService;
            this._windDataService = WindDataService;
            this._waveDataService = WaveDataService;
            this._forecastDataService = ForecastDataService;
            this._scheduleTaskService = scheduleTaskService;
            this._dateTimeHelper = dateTimeHelper;
            this._settingService = settingService;
            this._storeService = storeService;
            this._workContext = workContext;
        }

        #endregion

       
        public ActionResult WindAlertAdmin()
        {
            return View();
        }

        #region Settings
        public ActionResult WindalertSettings()
        {
            var model = new WindAlertSettingsModel();
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
            model.ActiveStoreScopeConfiguration = storeScope;
            //windalert settings
            var windAlertSettings = _settingService.LoadSetting<WindAlertSettings>(storeScope);
            model.BlockCameras = windAlertSettings.BlockCameras;
            model.BlockForecast = windAlertSettings.BlockForecast;
            model.BlockWindTable = windAlertSettings.BlockWindTable;
            model.PictureMaximumSizeBytes = windAlertSettings.PictureMaximumSizeBytes;
            if (storeScope > 0)
            {
                model.BlockCameras_OverrideForStore = _settingService.SettingExists(windAlertSettings, x => x.BlockCameras, storeScope);
                model.BlockForecast_OverrideForStore = _settingService.SettingExists(windAlertSettings, x => x.BlockForecast, storeScope);
                model.BlockWindTable_OverrideForStore = _settingService.SettingExists(windAlertSettings, x => x.BlockWindTable, storeScope);
                model.PictureMaximumSizeBytes_OverrideForStore = _settingService.SettingExists(windAlertSettings, x => x.PictureMaximumSizeBytes, storeScope);
            }
            return View(model);
        }

        [HttpPost]
        [FormValueRequired("save")]
        public ActionResult WindalertSettings(WindAlertSettingsModel model)
        {
            //load settings for a chosen store scope
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
            //windalert settings
            var windAlertSettings = _settingService.LoadSetting<WindAlertSettings>(storeScope);

            windAlertSettings.BlockCameras = model.BlockCameras;
            windAlertSettings.BlockForecast = model.BlockForecast;
            windAlertSettings.BlockWindTable = model.BlockWindTable;
            windAlertSettings.PictureMaximumSizeBytes= model.PictureMaximumSizeBytes;

            if (model.BlockCameras_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(windAlertSettings, x => x.BlockCameras, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(windAlertSettings, x => x.BlockCameras, storeScope);

            if (model.BlockForecast_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(windAlertSettings, x => x.BlockForecast, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(windAlertSettings, x => x.BlockForecast, storeScope);

            if (model.BlockWindTable_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(windAlertSettings, x => x.BlockWindTable, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(windAlertSettings, x => x.BlockWindTable, storeScope);

            if (model.PictureMaximumSizeBytes_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(windAlertSettings, x => x.PictureMaximumSizeBytes, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(windAlertSettings, x => x.PictureMaximumSizeBytes, storeScope);

            _settingService.ClearCache();

            SuccessNotification("Updated");
            return RedirectToAction("WindalertSettings");
        }

        #endregion 

        #region wind data

        public ActionResult InsertWindDataRow()
        {
            var spotStations = _spotService.GetAllSpots(isStation:true);
            foreach (var spotStation in spotStations)
            {
                var stationData = _windDataService.UpdateStation(spotStation);
                var lastStation = _windDataService.GetWindDataBySpotIdTop1(spotStation.Id);
                if (lastStation == null)
                    _windDataService.InsertWindData(stationData);
                else if (lastStation.StationTime != stationData.StationTime)
                    _windDataService.InsertWindData(stationData);
            }
            ViewBag.Message = "All stations updated";
            return View("WindAlertAdmin");
        }

        public ActionResult RunWindDataTest()
        {
            ViewBag.CurrentUserDateTime = _dateTimeHelper.ConvertToUserTime(DateTime.Now);
            var stations = _spotService.GetAllSpots(isStation:true);
            var windDatasModel = new List<WindDataModel>();
            foreach (var station in stations)
            {
                var stationData = _windDataService.UpdateStation(station);
                var windData = new WindDataModel()
                {
                    StationTime = stationData.StationTime,
                    StationAdjustedTime = stationData.StationAdjustedTime,
                    WindSpeed = stationData.WindSpeed,
                    WindGust = stationData.WindGust,
                    WindSpeedAgv = stationData.WindSpeedAgv,
                    WindDirection = stationData.WindDirection,
                    StationName = station.Name,
                    Barometer = stationData.Barometer,
                    CloudBase = stationData.CloudBase,
                    DewPoint = stationData.DewPoint,
                    Humidity = stationData.Humidity,
                    Temperture = stationData.Temperture
                };
                windDatasModel.Add(windData);
            }
            var gridModel = new DataSourceResult
            {
                Data = windDatasModel,
                Total = windDatasModel.Count()
            };
            return View(gridModel);
        }

        public ActionResult BuildWindDataTable()
        {
            ViewBag.CurrentUserDateTime = _dateTimeHelper.ConvertToUserTime(DateTime.Now);
            var stations = _spotService.GetAllSpots(isStation:true);
            var model = new  WindDataTableModel();
            foreach (var station in stations)
            {
                var stationData = _windDataService.GetWindDataBySpotIdTop1(station.Id);
                if (stationData == null)
                    return null;
                var windDataRow = new WindDataRowModel()
                {
                    StationAdjustedTime = stationData.StationAdjustedTime,
                    WindSpeed = stationData.WindSpeed,
                    WindGust = stationData.WindGust,
                    WindDirection = stationData.WindDirection,
                    StationName = station.Name,
                };
                model.TableRows.Add(windDataRow);
            }
            return PartialView (model);
        }

        #endregion

        #region wave

        public ActionResult InsertWaveDataRow()
        {
            var spots = _spotService.GetAllSpots(isWave:true);
            foreach (var spot in spots)
            {
                if (!string.IsNullOrEmpty(spot.WaveDataUrl))
                {
                    var spotData = _waveDataService.UpdateWaveSpot(spot);
                    if (spotData != null)
                    {
                        var lastWave = _waveDataService.GetWaveDataBySpotIdTop1(spot.Id);
                        if (lastWave == null)
                            _waveDataService.InsertWaveData(spotData);
                        else if (lastWave.WaveTimeUTC != spotData.WaveTimeUTC)
                            _waveDataService.InsertWaveData(spotData);
                    }
                }
            }
            ViewBag.Message = "All stations updated";
            return View("WindAlertAdmin");
        }
 
        public ActionResult RunWaveDataTest()
        {
            ViewBag.CurrentUserDateTime = _dateTimeHelper.ConvertToUserTime(DateTime.Now);
            var spots = _spotService.GetAllSpots(isWave:true);
            var waveDatasModel = new List<WaveDataModel>();
            foreach (var spot in spots)
            {
                if (!string.IsNullOrEmpty(spot.WaveDataUrl))
                {
                    var spotData = _waveDataService.UpdateWaveSpot(spot);
                    if (spotData != null)
                    {
                        var waveData = new WaveDataModel()
                        {
                            WaveTime = spotData.WaveTimeUTC,
                            WaveAdjustedTime = spotData.WaveAdjustedTime,
                            Hmax = spotData.Hmax,
                            Hs = spotData.Hs,
                            Hthird = spotData.Hthird,
                            Direction = spotData.Direction,
                            SpotName = spot.Name,
                            Tav = spotData.Tav,
                            Tz = spotData.Tz,
                            Tp = spotData.Tp,
                            Temperture = spotData.Temperture
                        };
                        waveDatasModel.Add(waveData);
                    }
                }
            }
            var gridModel = new DataSourceResult
            {
                Data = waveDatasModel,
                Total = waveDatasModel.Count()
            };
            return View(gridModel);
        }


        public ActionResult BuildWaveDataTable()
        {
            ViewBag.CurrentUserDateTime = _dateTimeHelper.ConvertToUserTime(DateTime.Now);
            var spots = _spotService.GetAllSpots(false);
            var model = new WaveDataTableModel();
            foreach (var spot in spots)
            {
                if (!string.IsNullOrEmpty(spot.WaveDataUrl))
                {
                    var spotData = _waveDataService.GetWaveDataBySpotIdTop1(spot.Id);
                    if (spotData == null)
                        return null;
                    var waveDataRow = new WaveDataRowModel()
                    {
                        SpotAdjustedTime = spotData.WaveAdjustedTime,
                        Hmax = spotData.Hmax,
                        Hs = spotData.Hs,
                        Direction = spotData.Direction,
                        SpotName = spot.Name,
                    };
                    model.TableRows.Add(waveDataRow);
                }
            }
            return PartialView(model);
        }
        #endregion

        #region Forecast

        public ActionResult InsertForecastDataRow()
        {
            //var test = _forecastDataService.checkForecastDate();
            var spots = _spotService.GetAllSpots(isForecast:true);
            foreach (var spot in spots)
            {
                if (spot.IsForecast)
                {
                    var forecastDatas = _forecastDataService.UpdateForecastSpot(spot);
                    if (forecastDatas != null)
                    {
                        foreach (var forecastData in forecastDatas)
                        {
                            if (_forecastDataService.ForecastNameExists(forecastData.Name, spot.Id))
                            {
                                var CurrentforecastData = _forecastDataService.GetForecastDataBySpotIdAndName(spot.Id, forecastData.Name);
                                CurrentforecastData.CreatedOnUtc = forecastData.CreatedOnUtc;
                                CurrentforecastData.ForecastTime = forecastData.ForecastTime;
                                CurrentforecastData.WindSpeed = forecastData.WindSpeed;
                                CurrentforecastData.WindDirection = forecastData.WindDirection;
                                CurrentforecastData.Height = forecastData.Height;
                                CurrentforecastData.Period = forecastData.Period;
                                CurrentforecastData.WaveDirection = forecastData.WaveDirection;
                                _forecastDataService.UpdateForecastData(CurrentforecastData);
                            }
                            else
                            {
                                _forecastDataService.InsertForecastData(forecastData);
                            }
                        }
                    }
                }
            }
            ViewBag.Message = "All forecasts updated";
            return View("WindAlertAdmin");
        }

        //public ActionResult RunForecastDataTest()
        //{
        //    ViewBag.CurrentUserDateTime = _dateTimeHelper.ConvertToUserTime(DateTime.Now);
        //    var spots = _spotService.GetAllSpots(isforecast:true);
        //    var forecastDatasModel = new List<ForecastDataModel>();
        //    foreach (var spot in spots)
        //    {
        //        if (spot.IsForecast)
        //        {
        //            var spotData = _forecastDataService.UpdateForecastSpot(spot);
        //            var forecastData = new ForecastDataModel()
        //            {
        //                ForecastTime  = spotData.ForecastTime,
        //                WindSpeed = spotData.WindSpeed,
        //                WindDirection = spotData.WindDirection,
        //                Height = spotData.Height,
        //                WaveDirection = spotData.WaveDirection,
        //                Period  = spotData.Period,
        //                SpotName = spot.Name,
        //            };
        //            forecastDatasModel.Add(forecastData);
        //        }
        //    }
        //    var gridModel = new GridModel<ForecastDataModel>
        //    {
        //        Data = forecastDatasModel,
        //        Total = forecastDatasModel.Count()
        //    };
        //    return View(gridModel);
        //}

        #endregion
    }

}
